; (function () {
    return
    // 这个是原来的数组原型对象.
    const arrayProto = Array.prototype
    // 这个应该是复制一个对象
    const arrayMethods = Object.create(arrayProto)


        ;[
            'push',
            'pop',
            'shift',
            'unshift',
            'splice',
            'sort',
            'reverse'
        ]
            .forEach(function (method) {
                // 缓存原始方法
                const original = arrayProto[method]

                Object.defineProperty(arrayMethods, method, {
                    value: function mutator(...args) {
                        return original.apply(this, args)
                    },
                    enumerable: false,
                    writable: true,
                    configurable: true
                })
            })

    class Observer {
        constructor(value) {
            this.value = value

            if (Array.isArray(value)) {
                // 在这里改变 指定的value这个数组的原型指向.
                // 就可以避免污染全局的数组.
                value.__proto__ = arrayMethods // 新增
            } else {
                this.walk(value)
            }

            // 这里还有部分代码 在watcher里面已经有了
            // walk(){}
        }
    }
    console.log(arrayMethods)
})()

// 针对上面的array劫持进行举例,举例劫持数据原型
;(function(){
  return
  class Obj {
    constructor(name,age){
        this.name = name || "张三"
        this.age = age || 18
    }
    setHello(){
        console.log("你好,我是"+this.name)
    }
    setHey(){
        console.log("setHey,我是"+this.age)
    }
  }
//  ===================== 正常逻辑下使用原型上的方法
//  let obj = new Obj("李四",19)
//  obj.setHello() //你好,我是李四
//  =====================

//   下面是开始劫持代码

//  先把Obj的prototype复制给objPrototype 其实是缓存下来
    let objPrototype = Obj.prototype
    let newPrototype = Object.create(objPrototype) // 这一步是继承原来的原型
    Object.defineProperty(newPrototype, 'setHello', {
        value: function mutator(...args) {
            console.log("我是被劫持的函数",this)
            return objPrototype.setHello.apply(this, args)
        },
        enumerable: false,
        writable: true,
        configurable: true
    })

    let obj = new Obj("李四",19)
    obj.__proto__ = newPrototype
    obj.setHello()  // 我是被劫持的函数  //这个就是被劫持后
                    // 你好,我是李四
    obj.setHey() // setHey,我是19 // 因为继承了原来的方法所以再往上找还是可以找到Obj的方法

    let obj2 = new Obj()
    obj2.setHello() // 你好,我是张三     //这个没有被劫持
    obj2.setHey() // setHey,我是18
})()